package code

import (
	"fmt"
	"os"
)

// defer 用于延迟调用, 在return/panic之前执性
// 多个defer按照先进后出的顺序执行

func Defer01() {
	x := 10
	defer func(x int) {
		x++
		// 11
		fmt.Println("defer x = ", x)
	}(x)
	x++
	// 11
	fmt.Println("x = ", x)
	return
}

func Defer02() {
	x := 10
	defer func(x *int) {
		// 12
		*x++
		fmt.Println("defer x = ", *x)
	}(&x)
	x++
	// 11
	fmt.Println("x = ", x)
	return
}

// go 中 return不是原子操作
func testDefer() (result int) {
	i := 1
	defer func() {
		// go 中 return不是原子操作
		// return 语句 1=> 赋值 > 调用defer > 返回
		result++
	}()
	return i
}

func Defer03() {
	result := testDefer()
	//2
	fmt.Println(result)
}

// defer一定要定义在return或是panic之前, 否则会执性
func Defer04() {
	// defer不会执行
	// 主动调用os.Exit不会执行defer
	defer func() {
		fmt.Println("defer")
	}()
	// 退出进程
	os.Exit(-1)
}
